import React, { FC, useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { Input, Space, Badge, Alert, Tooltip, Switch } from 'antd';
import { isArray, isNil, isEmpty, isFunction } from 'lodash';
import { ColumnType } from 'antd/lib/table';

import { Content } from '@components/Page';
import CollapseQueryBar from '@components/CollapseQueryBar';
import { useForm } from '@components/Form';
import Table from '@components/Table';
import Button from '@components/Button';
import Icons from '@components/Icons';
import EditDrawerForm from '@components/EditDrawerForm';

import { COMMON_PAGINATION, COMMON_REQUIRE_RULE, VALIDATE_COMMON_CODE } from '@utils/config';
import { getDictionaryListApi } from '@services/service';
import { Status } from '@enumTypes/enumTypes';
import request from '@utils/request';
import {
  useResetFormOnCloseModal,
  generateCommonSelect,
  generateCommonDeleteModal,
  setOtherTypeValue
} from '@utils/renderer';
import { getPropValueByValue, getFormValues } from '@utils/util';
import notification from '@utils/notification';

import styles from './index.module.less';
import AssignSubFunction from './AssignSubFunction';

const { TextArea } = Input;

interface RoleSettingProps {}

const RoleSetting: FC<RoleSettingProps> = () => {
  const [loading, setLoading] = useState<boolean>(false);
  const [saveLoading, setSaveLoading] = useState<boolean>(false);

  // 字典数据
  const [statusList, setStatusList] = useState<any[]>([]);

  const [tableData, setTableData] = useState<any[]>([]);
  const [pagination, setPagination] = useState<any>(COMMON_PAGINATION);
  const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([]);
  const [selectedRows, setSelectedRows] = useState<any[]>([]);
  const [currentLine, setCurrentLine] = useState<any>({});

  const [operationType, setOperationType] = useState<string>('');
  const [openFlag, setOpenFlag] = useState<boolean>(false);

  const [queryForm] = useForm(); // 查询表单
  const [editForm] = useForm(); // 编辑表单

  const assignSubfunctionRef: any = useRef();

  useResetFormOnCloseModal({ form: editForm, openFlag });

  /** 查询设置字典数据 */
  const handleQueryDictionaryList = useCallback(() => {
    getDictionaryListApi(['RB_STATUS']).then((res: any) => {
      if (isArray(res)) {
        const [statusList = []] = res || [];
        setStatusList(statusList);
      }
    });
  }, []);

  /** 查询表格数据 */
  const handleQueryData = useCallback((params?: any) => {
    setLoading(true);

    request({
      url: '/system/role',
      method: 'GET',
      params: { ...COMMON_PAGINATION, ...params }
    })
      .then((res: any) => {
        if (res) {
          const { current, size, total, records = [] } = res;
          // 设置分页数据
          setPagination({ ...COMMON_PAGINATION, current, size: size, total });
          setTableData(records);
          // 查询重置勾选
          setSelectedRowKeys([]);
          setSelectedRows([]);
          setCurrentLine({});
        }
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

  useEffect(() => {
    handleQueryDictionaryList();
    handleQueryData();
  }, [handleQueryData, handleQueryDictionaryList]);

  /** 表单查询 */
  const handleSearch = useCallback(
    (values: any) => {
      handleQueryData(values);
    },
    [handleQueryData]
  );

  /** 分页切换重新查询表格数据 */
  const handleTableChange = useCallback(
    async ({ current, size }: any) => {
      const fields = await getFormValues(queryForm);
      handleQueryData({ ...fields, current, size });
    },
    [handleQueryData, queryForm]
  );

  /** 打开 新增|编辑 抽屉 */
  const handleOpenEditDrawer = useCallback(
    (type: string) => {
      // 设置操作类型
      setOperationType(type);

      if (type === 'update') {
        // 设置抽屉表单数据
        editForm.setFieldsValue(selectedRows[0] || {});
      }

      // 打开抽屉
      setOpenFlag(true);
    },
    [editForm, selectedRows]
  );

  /** 保存 */
  const handleSave = useCallback(async () => {
    // 表单未修改
    if (!editForm.isFieldsTouched()) {
      // 关闭抽屉
      setOpenFlag(false);
      return;
    }

    // 校验获取值
    const fields = await editForm.validateFields();

    // 校验通过
    if (fields) {
      setSaveLoading(true);
      request({
        url: '/system/role',
        method: operationType === 'update' ? 'PUT' : 'POST',
        data: { ...selectedRows[0], ...fields }
      })
        .then(async (res: any) => {
          if (res) {
            notification.success();
            // 关闭抽屉
            setOpenFlag(false);
            const params = await getFormValues(queryForm);
            const { current, size } = pagination;
            // 查询最新数据
            handleQueryData({ ...params, current, size });
          }
        })
        .finally(() => {
          setSaveLoading(false);
        });
    }
  }, [editForm, handleQueryData, operationType, pagination, queryForm, selectedRows]);

  /** 删除 */
  const handleDelete = useCallback(() => {
    if (isEmpty(selectedRowKeys)) return;

    generateCommonDeleteModal({
      title: '是否确定删除这些角色?',
      onOk() {
        setLoading(true);
        request({
          url: '/system/role',
          method: 'DELETE',
          data: selectedRowKeys
        })
          .then(async (res: any) => {
            if (res) {
              notification.success();
              const params = await getFormValues(queryForm);
              // 查询最新数据
              handleQueryData(params);
            }
          })
          .finally(() => {
            setLoading(false);
          });
      }
    });
  }, [handleQueryData, queryForm, selectedRowKeys]);

  /** 菜单功能树刷新 */
  const handleQueryTree = useCallback(() => {
    if (!assignSubfunctionRef.current) return;

    const { queryTree } = assignSubfunctionRef.current || {};
    if (isFunction(queryTree)) queryTree();
  }, []);

  /** 菜单功能树保存 */
  const handleSaveTree = useCallback(() => {
    if (!assignSubfunctionRef.current) return;

    const { saveTree } = assignSubfunctionRef.current || {};
    if (isFunction(saveTree)) saveTree();
  }, []);

  /** 查询条配置列表 */
  const queryFromItems = useMemo(
    () => [
      {
        name: 'name',
        label: '角色名称',
        children: <Input />
      },
      {
        name: 'code',
        label: '角色编码',
        children: <Input />
      },
      {
        name: 'status',
        label: '状态',
        children: generateCommonSelect(statusList)
      }
    ],
    [statusList]
  );

  /** 编辑表单配置列表 */
  const editFormItems = useMemo(
    () => [
      {
        name: 'name',
        label: '角色名称',
        rules: [COMMON_REQUIRE_RULE],
        children: <Input />
      },
      {
        name: 'code',
        label: '角色编码',
        rules: [COMMON_REQUIRE_RULE, VALIDATE_COMMON_CODE],
        tooltip: VALIDATE_COMMON_CODE.message,
        children: <Input disabled={operationType === 'update'} allowClear />
      },
      {
        name: 'status',
        label: '状态',
        valuePropName: 'checked',
        rules: [COMMON_REQUIRE_RULE],
        ...setOtherTypeValue(1, 0),
        children: <Switch checkedChildren="启用" unCheckedChildren="禁用" />
      },
      {
        name: 'remark',
        label: '备注',
        children: <TextArea />
      }
    ],
    [operationType]
  );

  /** 表格列配置 */
  const columns: ColumnType<any>[] = useMemo(
    () => [
      {
        title: '角色名称',
        dataIndex: 'name'
      },
      {
        title: '角色编码',
        dataIndex: 'code'
      },
      {
        title: '状态',
        align: 'center',
        dataIndex: 'status',
        width: 100,
        render: value => {
          return (
            !isNil(value) && (
              <Space>
                <Badge status={Status.enable === value ? 'success' : 'error'} />
                {getPropValueByValue(value, statusList)}
              </Space>
            )
          );
        }
      }
    ],
    [statusList]
  );

  /** 勾选配置 */
  const rowSelection = {
    selectedRowKeys,
    onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: any[]) => {
      setSelectedRowKeys(newSelectedRowKeys);
      setSelectedRows(newSelectedRows);
    }
  };

  return (
    <Content loading={loading}>
      <div className={styles.twoToOneFlexDivWrapper}>
        <div className={styles.leftDivWrapper}>
          <CollapseQueryBar
            form={queryForm}
            queryFromItems={queryFromItems}
            handleSearch={handleSearch}
            isIconBtn
            columns={2}
          />
          <div style={{ textAlign: 'right', marginBottom: 8 }}>
            <Space>
              <Button type="primary" onClick={() => handleOpenEditDrawer('create')}>
                新增
              </Button>
              <Button
                type="primary"
                disabled={selectedRows.length !== 1}
                onClick={() => handleOpenEditDrawer('update')}
              >
                修改
              </Button>
              <Button
                type="primary"
                danger
                disabled={!selectedRowKeys.length}
                onClick={handleDelete}
              >
                删除
              </Button>
            </Space>
          </div>
          <Table
            rowKey="id"
            columns={columns}
            dataSource={tableData}
            pagination={pagination}
            onChange={handleTableChange}
            rowSelection={rowSelection}
            sticky // 表头随页面滚动固定
            onRow={record => {
              return {
                onDoubleClick: () => setCurrentLine(record)
              };
            }}
          />
        </div>
        <div className={styles.rightDivWrapper}>
          <Alert
            banner
            type="info"
            message="双击角色行 -> 分配菜单/子功能 -> 保存"
            icon={<Icons type="AlertOutlined" />}
            className={styles.rightAlert}
            action={
              <>
                <Tooltip placement="bottomLeft" title="菜单功能树刷新">
                  <Button
                    disabled={!currentLine.id}
                    shape="circle"
                    type="text"
                    icon={<Icons type="RedoOutlined" />}
                    onClick={handleQueryTree}
                  />
                </Tooltip>
                <Tooltip placement="bottomLeft" title="保存菜单功能树修改">
                  <Button
                    disabled={!currentLine.id}
                    shape="circle"
                    type="text"
                    icon={<Icons type="SaveOutlined" />}
                    onClick={handleSaveTree}
                  />
                </Tooltip>
              </>
            }
          />
          {currentLine.id && (
            <div className={styles.rightAssignSubFunctionDivWrapper}>
              <Badge.Ribbon text={currentLine.name}>
                <AssignSubFunction currentId={currentLine.id} ref={assignSubfunctionRef} />
              </Badge.Ribbon>
            </div>
          )}
        </div>
      </div>
      {openFlag && (
        <EditDrawerForm
          title={operationType === 'update' ? '编辑' : '新增'}
          openFlag={openFlag}
          setOpenFlag={setOpenFlag}
          form={editForm}
          handleSave={handleSave}
          loading={saveLoading}
          formItems={editFormItems}
          initialValues={{
            status: 1
          }}
        />
      )}
    </Content>
  );
};

export default RoleSetting;
